home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / gfxlib.c < prev    next >
C/C++ Source or Header  |  1996-05-23  |  9KB  |  311 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   *   Graphics.library replacement
  5.   *
  6.   *   (c) 1996 by Christian Schmitt   <schmittc@uni-freiburg.de>
  7.   *
  8.   *   (c) 1996 by Markus Gietzen
  9.   *
  10.   */
  11.  
  12. #include "sysconfig.h"
  13. #include "sysdeps.h"
  14.  
  15. #include <assert.h>
  16.  
  17. #include "config.h"
  18. #include "options.h"
  19. #include "events.h"
  20. #include "memory.h"
  21. #include "custom.h"
  22. #include "newcpu.h"
  23. #include "xwin.h"
  24. #include "autoconf.h"
  25. #include "filesys.h"
  26. #include "gfxlib.h"
  27.  
  28.  
  29. /* Global variables etc. */
  30. static ULONG gfxlibname;
  31.  
  32. static CPTR Move,WritePixel,ReadPixel,SetRast,BltClear;
  33.  
  34.  
  35. static ULONG gfxl_WritePixel(void)
  36. {
  37.         CPTR rastport=regs.a[1],layer=longget(rastport);
  38.         CPTR bitmap=longget(rastport+4),adr=0L;
  39.         UWORD x=regs.d[0],minx,miny,maxx,maxy;
  40.         UWORD y=regs.d[1];
  41.         UBYTE new=0,old=0,pen=byteget(rastport+25),
  42.               depth=byteget(bitmap+5),pixel;
  43.         UWORD bpr=wordget(bitmap);
  44.         UWORD rows=wordget(bitmap+2);
  45.         CPTR Planeptr=longget(bitmap+8),Plane=0;
  46.         int i;
  47.  
  48.         if(layer!=0){
  49.                 rastport=longget(layer+12);
  50.                 pen=byteget(rastport+25);
  51.                 bitmap=longget(rastport+4);
  52.                 depth=byteget(bitmap+5);
  53.                 minx=wordget(layer+16);
  54.                 miny=wordget(layer+18);
  55.                 maxx=wordget(layer+20);
  56.                 maxy=wordget(layer+22);
  57.                 bpr=wordget(bitmap);
  58.                 rows=wordget(bitmap+2);
  59.         } else {
  60.                 minx=miny=0;
  61.                 maxx=bpr*8;
  62.                 maxy=rows;
  63.         }
  64.         y=y+miny;
  65.         x=x+minx;
  66.         if((x>maxx)||(y>maxy)){
  67.                 regs.d[0]=-1;
  68.                 return 0;
  69.         } else {
  70.                 for(i=0;i<depth;i++){
  71.                         Plane=longget(bitmap+8+4*i);
  72.                         old=byteget(Plane+y*bpr+x/8);
  73.                         if(!(pen&(1<<i))) new=old | (128>>(x%8));
  74.                         else new=old&(0xff-(128>>(x%8)));
  75.                         byteput(Plane+y*bpr+x/8,new);
  76.                 }
  77.     }
  78.         regs.d[0]=0;
  79.         return 0;
  80. }                    
  81.  
  82.  
  83. static ULONG gfxl_ReadPixel(void)
  84. {
  85.         CPTR rastport=regs.a[1];
  86.         CPTR bitmap=longget(rastport+4);
  87.         UWORD x=regs.d[0],y=regs.d[1],old;
  88.         UBYTE pen=0,depth=byteget(bitmap+5);
  89.         UWORD bpr=wordget(bitmap);
  90.         UWORD rows=wordget(bitmap+2);
  91.         CPTR PlanePtr=longget(bitmap+8),Plane=0;
  92.         int i;
  93.         for(i=0;i<depth;i++){
  94.                 Plane=longget(bitmap+8+4*i);
  95.                 old=byteget(Plane+y*bpr+x/8);
  96.                 if(((128>>(x%8))&old)) pen=pen+(1<<i);
  97.         }
  98.         regs.d[0]=pen;
  99.         return 0;
  100. }
  101.  
  102.  
  103. static ULONG gfxl_SetRast(void)       /* This function isn't working right now */
  104. {
  105.         CPTR rastport=regs.a[1],bitmap,PlanePtr,Plane,layer;
  106.         UBYTE pen=regs.d[0],depth,mode=byteget(rastport+28);
  107.         UWORD bpr,rows,minx=0,miny=0,maxx,maxy,dx,x,y,dy;
  108.         ULONG pattern,bits=0,new,old;
  109.         int i,j;
  110.  
  111.         layer=longget(rastport);
  112.         bitmap=longget(rastport+4);
  113.         PlanePtr=longget(bitmap+8);
  114.         bpr=wordget(bitmap);
  115.         rows=wordget(bitmap+2);
  116.         depth=byteget(bitmap+5);
  117.     switch(mode) {                /* What else do I have to do here ? */   
  118.             case 0 : break;
  119.         case 1 : pen=byteget(rastport+26);break;
  120.         default: break;
  121.         }
  122.         if(layer!=0) {
  123.                 rastport=longget(layer+12);
  124.                 minx=wordget(layer+16);
  125.                 miny=wordget(layer+18);
  126.                 maxx=wordget(layer+20);
  127.                 maxy=wordget(layer+22); 
  128.         } else {
  129.             maxx=bpr*8;
  130.         maxy=rows-1;
  131.     }
  132.         for(i=0;i<depth-1;i++){   
  133.                 Plane=longget(bitmap+8+i*4);
  134.                 if((pen&(1<<i))) pattern=0xffffffff; else pattern=0;
  135.                 for(y=miny;y<=maxy;y++){
  136.                         x=0;dx=0,dy=0;
  137.                         new=old=longget(Plane+y*bpr+minx);
  138.                         while(((minx+x)%8!=0)&&(x<=maxx)){
  139.                                 if(pattern==0xffffffff) new=new|(1<<(minx+x)%8);
  140.                                 else new=new&(0xff-(1<<(minx+x)%8));
  141.                                 x++;
  142.                         }
  143.                         if(x!=0) dx=1;
  144.                         byteput(Plane+y*bpr+minx,new);dy=x;
  145.                         while(8+dy<=maxx){
  146.                                 byteput(Plane+y*bpr+minx+dx,pattern);
  147.                                 dx++;
  148.                                 dy+=8;
  149.                         }
  150.                         x=0;
  151.                         new=byteget(Plane+y*bpr+minx+dx);
  152.                         while(((minx+dy+x)%8!=0)&&(x+dy<=maxx)){
  153.                                 if(pattern==0xffffffff) new=new|(1<<(minx+dy+x)%8);
  154.                                 else new=new&(0xff-(1<<(minx+dy+x)%8));
  155.                                 x++;
  156.                         } 
  157.                         byteput(Plane+y*bpr+minx+dx,new);
  158.                 }
  159.         }
  160.         return 0;
  161. }       
  162.    
  163.  
  164. static ULONG gfxl_BltClear(void)
  165. {
  166.         CPTR mem=regs.a[1];
  167.         ULONG count=regs.d[0];
  168.         ULONG flags=regs.d[1];
  169.         UWORD rows,bpr;
  170.         UWORD pattern=((flags&0xffff0000)>>16);
  171.         unsigned int i;
  172.  
  173.         if((flags&2)){
  174.                 bpr= (count&0x0000ffff);
  175.                 rows=(count>>16);
  176.                 count=bpr*rows;
  177.         }
  178.         if(flags&3){
  179.                 for(i=0;i<count;i+=2) wordput(mem+i,pattern);
  180.                 if(count%2) byteput(mem+(count/2)*2,pattern);
  181.         }else {
  182.                 for(i=0;i<count;i+=4) longput(mem+i,0);
  183.                 mem=mem+(count/4)*4;
  184.                 switch(count%4) {
  185.                         case 0 : break;
  186.                         case 1 : byteput(mem,0);break;
  187.                         case 2 : wordput(mem,0);break;
  188.                         case 3 : wordput(mem,0);byteput(mem+2,0);break;
  189.                         default: break; /* Ooops */
  190.                 }
  191.         }
  192.         return 0;
  193. }  
  194.  
  195. static ULONG gfxl_Move(void)
  196. {
  197.         CPTR rastport=regs.a[1];
  198.         WORD x=regs.d[0];
  199.         WORD y=regs.d[1];
  200.         /* Set new coordinate */
  201.         wordput(rastport+36,x);
  202.         wordput(rastport+38,y);
  203.         /* Set Linepatcnt */
  204.         byteput(rastport+30,0x0f);
  205.         return(0);
  206. }  
  207.  
  208.  
  209. /*
  210.  *  Initialisation  (called by AMIGA-OS !)
  211.  */
  212. static ULONG gfxlib_init(void)
  213. {
  214.         CPTR gfxbase;
  215.         CPTR sysbase=regs.a[6]; 
  216.         int i=0;
  217.  
  218.          /* Install new routines */
  219.      /* We have to call SetFunction here instead of writing direktly into the GfxBase,
  220.         because of the library checksum ! */
  221.  
  222.         regs.d[0]=0;
  223.         regs.a[1]=gfxlibname;
  224.         gfxbase=CallLib(sysbase, -408);  /* OpenLibrary */
  225.  
  226.         regs.a[1]=gfxbase;
  227.         regs.a[0]=-240;
  228.         regs.d[0]=Move;
  229.         CallLib(sysbase, -420);  /* SetFunction */
  230.  
  231.         regs.a[1]=gfxbase;
  232.         regs.a[0]=-324;
  233.         regs.d[0]=WritePixel;
  234.         CallLib(sysbase, -420);
  235.  
  236.         regs.a[1]=gfxbase;
  237.         regs.a[0]=-300;
  238.         regs.d[0]=BltClear;
  239.         CallLib(sysbase, -420);
  240.  
  241.         regs.a[1]=gfxbase;
  242.         regs.a[0]=-234;
  243.         regs.d[0]=SetRast;
  244.         CallLib(sysbase, -420);
  245.  
  246.         regs.a[0]=-318;
  247.         regs.d[0]=ReadPixel;
  248.         CallLib(sysbase,-420);
  249.  
  250.         return 0;
  251. }
  252.  
  253. /* 
  254.  *  Install the gfx-library-replacement 
  255.  */
  256. void gfxlib_install(void)
  257. {
  258.         ULONG begin, end, resname, resid;
  259.         int i;
  260.  
  261.         if(!use_gfxlib) return;
  262.     
  263.         fprintf(stderr, "Warning: you enabled the graphics.library replacement with -g\n"
  264.         "This may be buggy right now, and will not speed things up much.\n");
  265.  
  266.         resname = ds("UAEgfxlib.resource");
  267.         resid = ds("UAE gfxlib 0.1");
  268.  
  269.         gfxlibname = ds("graphics.library");
  270.  
  271.         begin = here();
  272.         dw(0x4AFC);             /* RTC_MATCHWORD */
  273.         dl(begin);              /* our start address */
  274.         dl(0);                  /* Continue scan here */
  275.         dw(0x0101);             /* RTF_COLDSTART; Version 1 */
  276.         dw(0x0805);             /* NT_RESOURCE; pri 5 */
  277.         dl(resname);            /* name */
  278.         dl(resid);              /* ID */
  279.         dl(here() + 4);         /* Init area: directly after this */
  280.  
  281.         calltrap(deftrap(gfxlib_init)); dw(RTS);
  282.  
  283.         /* start of code */
  284.  
  285.         Move=here();
  286.         calltrap(deftrap(gfxl_Move));
  287.         dw(RTS);
  288.  
  289.         WritePixel=here();
  290.         calltrap(deftrap(gfxl_WritePixel));
  291.         dw(RTS);
  292.  
  293.         ReadPixel=here();
  294.         calltrap(deftrap(gfxl_ReadPixel));
  295.         dw(RTS); 
  296.  
  297.         SetRast=here();
  298.         calltrap(deftrap(gfxl_SetRast));
  299.         dw(RTS); 
  300.  
  301.         BltClear=here();
  302.         calltrap(deftrap(gfxl_BltClear));
  303.         dw(RTS);
  304.  
  305.         end = here();
  306.         org(begin + 6);
  307.         dl(end);
  308.  
  309.         org(end);
  310. }
  311.